package com.zmh.wt.healthmonitor.utils;

import com.zmh.wt.healthmonitor.entity.TxtFileDo;
import org.springframework.scheduling.annotation.Async;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class TxtUtil {
    public static void main(String[] args) throws IOException {
        //读
        TxtFileDo txtFileDo = readTxtByPath("D:\\FtpCenter\\HH_WF10001_WT6_CH1_20000101000541.txt");
        System.out.println(txtFileDo.getMax());
        System.out.println(txtFileDo.getMin());

        TxtFileDo highpassDo = highpass(txtFileDo.getData());
        TxtUtil.writeTxtFile("D:\\FtpCenter\\HH.txt",highpassDo.getData());
        //转wav
//        Txt2WavUtil.doubleDataToWavFile(highpassDo.getData(), "A01-20190722131913", highpassDo.getMax(), highpassDo.getMin());
    }

    //    private static double rate = 0.000000001;
//    private static Double[] audha = {1.0, -1.98388104166084, 0.984009917549517};
    //高通滤波器参数设置 1KHZ 采样率 44100
    private static Double[] audha = {1.0, -1.7991, 0.8175};
//    private static Double[] audha = {1.0,-3.62784420219027,4.95122513325103,-3.01192428150538,0.688887685664050};


    private static Double[] audhb = {0.9042, -1.8083, 0.9042};
//    private static Double[] audhb = {0.829992581413170,-3.31997032565268,4.97995548847902,-3.31997032565268,0.829992581413170};


    private static Double[] in;
    private static Double[] out;
    /**
     * 波后数据
     */
    private static Double[] outData;

    /**
     * 高通滤波 1kHZ
     * 采样率 44100
     *
     * @param signal
     * @return
     */
    public static TxtFileDo highpass(Double[] signal) {
        return filter(signal, audha, audhb);
    }

    /**
     * 读txt文件
     *
     * @param filePath
     * @return
     */
    public static TxtFileDo readTxtByPath(String filePath) {
        if (!filePath.endsWith("txt")) {
            throw new RuntimeException("the file is not endWith txt");
        }
        BufferedReader reader;
        FileReader fileReader;

        //文件读取结果
        List<Double> result = new ArrayList<>();
        //文件读取结果输出
        Double[] fileReaderResult;

        try {
            fileReader = new FileReader(filePath);
            reader = new BufferedReader(fileReader);
            //按行读取
            String line = reader.readLine();
            while (line != null) {
                //将读取的数据放入到集合中
                result.add(Double.valueOf(line));
                line = reader.readLine();
            }
            fileReader.close();
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        fileReaderResult = new Double[result.size()];
        Double max = Double.MIN_VALUE;
        Double min = Double.MAX_VALUE;
        for (int i = 0; i < result.size(); i++) {
            Double cur = result.get(i);
            fileReaderResult[i] = cur;
            max = Math.max(cur, max);
            min = Math.min(cur, min);
        }
        int length = result.size();

        TxtFileDo txtFileDo = TxtFileDo.builder().data(fileReaderResult)
                .max(max)
                .min(min)
                .build();
        return txtFileDo;
    }

    /**
     * 删除文件
     * @param filePath
     * @return
     */
    public static Boolean deleteFileByAbsolutePath(String filePath){
        File file = new File(filePath);
        if (file.isFile() && file.exists()) {
            file.delete();
            return true;
        } else {
            return false;
        }
    }

    /**
     * 将double数组写入文件
     */
    public static void writeTxtFile(String filePath, double[] data) {
        if (!filePath.endsWith("txt")) {
            throw new RuntimeException("the filename is wrong, not endwith txt");
        }
        FileWriter fileWriter;
        BufferedWriter writer;
        try {
            fileWriter = new FileWriter(filePath);
            writer = new BufferedWriter(fileWriter);
            for (double l : data) {
                String line = String.valueOf(l);
                writer.write(line);
                writer.newLine();
            }
            writer.close();
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void writeTxtFile(String filePath, Double[] data) {
        if (!filePath.endsWith("txt")) {
            throw new RuntimeException("the filename is wrong, not endwith txt");
        }
        FileWriter fileWriter;
        BufferedWriter writer;
        try {
            fileWriter = new FileWriter(filePath);
            writer = new BufferedWriter(fileWriter);
            for (double l : data) {
                String line = String.valueOf(l);
                writer.write(line);
                writer.newLine();
            }
            writer.close();
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

//    public static Double[] lowpass(Double[] signal) {
//        return filter(signal, audla, audlb);
//    }

    private static TxtFileDo filter(Double[] signal, Double[] a, Double[] b) {
        in = new Double[b.length];
        out = new Double[a.length - 1];
        outData = new Double[signal.length];
        Double max = Double.MIN_VALUE;
        Double min = Double.MAX_VALUE;
        for (int i = 0; i < signal.length; i++) {

            System.arraycopy(in, 0, in, 1, in.length - 1);  //in[1]=in[0],in[2]=in[1]...
            in[0] = signal[i];
            //calculate y based on a and b coefficients
            //and in and out.
            Double y = 0.0;
            for (int j = 0; j < b.length; j++) {
                if (in[j] != null) {
                    y += b[j] * in[j];
                }
            }
            for (int j = 0; j < a.length - 1; j++) {
                if (out[j] != null) {
                    y -= a[j + 1] * out[j];
                }
            }
            //shift the out array
            System.arraycopy(out, 0, out, 1, out.length - 1);
            out[0] = y;
            outData[i] = y;
            max = Math.max(max, y);
            min = Math.min(min, y);
        }
        TxtFileDo highpassDataDo = TxtFileDo.builder()
                .data(outData)
                .max(max)
                .min(min)
                .build();

        return highpassDataDo;
    }
}
